
/********************************************************************************
 * Copyright(c) 2020-2025 VINCENT_WY All rights reserved.
 * - Filename
 * - Author  Vincent
 * - Version V1.0.0
 * - Date    2023/09/21
 * - Brief
 * - FunctionList:
 ******************************************************************************
 * History:
 *
 *
 *
 ******************************************************************************
 */
#include "FileReader.h"
#include "logutil.h"
#include <dirent.h>
#include <exception>
#include <filesystem>
#include <string.h>
#define MAX_FRAME_READ (int)250
bool isFileExit(std::string const &fullString, std::string const &ending)
{
  if (fullString.length() >= ending.length())
  {
    return (0 == fullString.compare(fullString.length() - ending.length(),
                                    ending.length(), ending));
  }
  else
  {
    return false;
  }
}

FileReader::FileReader(const std::string &root, bool buffer)
{
  LOGD("input folder path: %s", root.c_str());
  _root = root;
  if (root.back() != '/')
  {
    _root.append("/");
  }
  DIR *pDir;
  struct dirent *ptr;
  if (!(pDir = opendir(_root.c_str())))
  {
    LOGE("Folder doesn't Exist!");
    return;
  }

  int count = 0;
  std::map<int, std::string> mFileMap;
  while ((ptr = readdir(pDir)) != 0)
  {
    if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0)
    {

      FileInfo frame;
      std::string mFileName = ptr->d_name;
      std::string freq = mFileName;
      int nPos = freq.find("_");
      if (nPos != -1)
      {
        freq = freq.substr(0, nPos);
        mFileMap.insert(std::make_pair(std::atoi(freq.c_str()), mFileName));
      }
    }
  }
  closedir(pDir);

  for (auto &&it : mFileMap)
  {
    FileInfo frame;
    if (getFrameInfo(_root, it.second, frame, buffer)) {
      _fileInfoMap.insert(std::make_pair(frame.freq, frame));
      if (count++ > MAX_FRAME_READ && buffer) break;
    }
  }
}

FileReader::~FileReader() { _fileInfoMap.clear(); }

std::vector<FileInfo> FileReader::getFileInfoList()
{
  std::vector<FileInfo> fileList;

  for (auto &&it : _fileInfoMap)
  {
    fileList.emplace_back(it.second);
    LOGD("get file: %d %s", it.first, it.second.fileName.c_str());
  }
  return fileList;
}

bool FileReader::getFrameInfo(const std::string &root, std::string name,
                              FileInfo &frame, bool bufferFrame)
{
  try
  {
    long long int tm = 0;
    int strid = 0;
    if (sscanf(name.c_str(), "%d_%lld_%dx%dx%d.nv21", &frame.freq, &frame.timestamp,
           &strid, &frame.width, &frame.height) != 5) {
      LOGD("file name %s not match pattern, skip", name.c_str());
      return false;
    }
    frame.fileName = root + name;
    if (bufferFrame) {
      std::shared_ptr<uint8_t[]> nv12_buffer(new uint8_t[frame.width * frame.height * 3 / 2],
                                             [](uint8_t* p) { delete[] p; });
      FILE* fp_r = fopen(frame.fileName.c_str(), "rb");
      if (NULL == fp_r) {
        LOGE("failed to open the fp_r");
        fclose(fp_r);
        return false;
      }
      // 将文件数据读到image buffer中
      fread(nv12_buffer.get(), sizeof(unsigned char), frame.width * frame.height * 3 / 2, fp_r);
      fclose(fp_r);
      frame.buffer = std::move(nv12_buffer);
    }
    LOGD("%d, %lld, %d, %d, %d, %s", frame.freq, frame.timestamp, strid,
           frame.height, frame.width, frame.fileName.c_str());
    return true;
  }
  catch (std::exception &e)
  {
    LOGE("%s", e.what());
    return false;
  }
}
